"""
Case Type   : datakit并行安装数据库
Case Name   : 创建并行安装任务，安装包选择轻量版，创建任务成功
Create At   : 2025/06/03
Owner       : @ningyali
Description :
    1.导入服务器
    2.添加用户
    3.获取安装包，存放本地
    4.上传安装包
    5.创建并行安装任务，安装包选择第4步上传的包
    6.查看草稿箱中并行安装任务列表
Expect      :
    1.成功
    2.成功
    3.执行成功
    4.执行成功
    5.创建任务成功
    6.可查看到第5步创建的任务
History     :
"""

import os
import subprocess
import unittest

import requests
from testcase.utils.Common import Common
from testcase.utils.CommonDatakit import CommonDatakit
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Logger import Logger
from testcase.utils.datakit_api.BaseOpsApi import BaseOpsApi
from testcase.utils.datakit_api.CommonApi import CommonApi
from yat.test import Node
from yat.test import macro


class Tools(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.log.info(f"-----{os.path.basename(__file__)} start-----")
        self.com_sh = CommonSH()
        self.common = Common('PrimaryRoot')
        self.pri_node = Node('PrimaryDbUser')
        self.pri_node_root = Node('PrimaryRoot')
        self.host_list = [self.pri_node_root]
        self.user = 'Batch_0004'
        self.db_version = macro.DATAKIT_RECENT_DB_VERSION
        self.pkg_name = 'pkg_batch_0004'
        self.pkg_version = 'LITE'

        text = '----prestep1:获取token expect:执行成功----'
        self.log.info(text)
        self.token = self.com_sh.get_token_value(macro.DATAKIT_PASSWD)
        self.log.info(self.token)
        self.assertNotIn("error", self.token.lower(), f'执行失败:{text}')

        self.com_api = CommonApi(self.token)
        self.base_ops_api = BaseOpsApi(self.token)
        self.datakit_sh = CommonDatakit(self.token)
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token}

        text = '----prestep2:获取当前os信息 expect:执行成功----'
        self.log.info(text)
        self.os_info = self.datakit_sh.get_os_info(self.pri_node_root)
        self.pkg_url = self.datakit_sh.join_pkg_url(
            self.pri_node_root, self.db_version, self.pkg_version)
        self.complete_pkg_url = f'{macro.DATAKIT_GET_PKG_URL}/{self.pkg_url}'
        self.save_pkg_path = os.path.join(
            macro.DB_BACKUP_PATH, os.path.basename(self.pkg_url))

    def test_batch_installation(self):
        text = '----step1:导入服务器 expect:成功----'
        self.log.info(text)
        self.datakit_sh.import_host(self.host_list)
        self.common.create_user(self.pri_node_root, self.user)

        text = '----step2:添加用户 expect:成功----'
        self.log.info(text)
        res3 = self.com_api.get_host_page(name=self.pri_node_root.ssh_host)
        self.host_id = res3.json()['rows'][0]['hostId']
        self.data3 = {"hostId": self.host_id,
                      "username": self.user,
                      "password": f"{macro.COMMON_PASSWD}"}
        res4 = self.com_api.post_hostUser(self.data3)
        self.log.info(f'res4.json():{res4.json()}')
        self.assertEqual(200, res4.json()['code'], '添加用户失败')

        self.log.info('获取hostUserId')
        api = f'/plugins/base-ops/clusterTask/hostUser/{self.host_id}'
        response = requests.get(url=self.base_ops_api.ip + api,
                                headers=self.headers, verify=False)
        self.log.info(f'response.text:{response.text}')
        self.host_user_id = None
        for item in response.json()["data"]:
            if item.get('hostId', None) == self.host_id:
                self.host_user_id = item.get('hostUserId')
        self.log.info(f'hostUserId:{self.host_user_id}')

        text = '----step3:获取安装包，存放本地 expect:执行成功----'
        self.log.info(text)
        wget_cmd = f'wget -P {macro.DB_BACKUP_PATH} -nv {self.complete_pkg_url}'
        ls_cmd = f'ls {macro.DB_BACKUP_PATH}|' \
                 f'grep "{os.path.basename(self.pkg_url)}"'
        self.log.info(wget_cmd)
        wget_res = subprocess.getoutput(wget_cmd)
        self.log.info(wget_res)
        self.assertNotIn('error', wget_res.lower(), f'执行成功:{text}')

        self.log.info(ls_cmd)
        ls_res = subprocess.getoutput(ls_cmd)
        self.log.info(ls_res)
        self.assertGreater(len(ls_res.strip()), 0, f'执行成功:{text}')

        text = '----step4:上传安装包 expect:执行成功----'
        self.log.info(text)
        api = '/plugins/base-ops/installPackageManager/v2/save/upload/'
        file_object = {
            "name": (None, self.pkg_name, None),
            "os": (None, self.os_info['os'], None),
            "osVersion": (None, self.os_info['os_version'], None),
            "cpuArch": (None, self.os_info['cpu_arch'], None),
            "packageVersionNum": (None, self.db_version, None),
            "packageVersion": (None, self.pkg_version, None),
            "packageUrl": (None, self.complete_pkg_url, None),
            "uploadFile": (os.path.basename(self.pkg_url),
                           open(self.save_pkg_path, 'rb'),
                           'application/gzip')
        }
        headers = {"Authorization": "Bearer " + self.token}
        response = requests.post(
            url=self.base_ops_api.ip + api, files=file_object,
            headers=headers, verify=False)
        self.log.info(f'response.text:{response.text}')
        self.assertEqual(response.json()["code"], 200, f'执行成功:{text}')

        text = '----step5:创建并行安装任务，安装包选择第4步上传的包 expect:创建任务成功----'
        self.log.info(text)
        self.log.info('获取packageId')
        api = f'/plugins/base-ops/installPackageManager/v2/list/package'
        data = {"name": "",
                "os": self.os_info['os'],
                "osVersion": self.os_info['os_version'],
                "cpuArch": self.os_info['cpu_arch'],
                "openGaussVersion": self.pkg_version,
                "openGaussVersionNum": self.db_version}
        response = requests.post(
            url=self.base_ops_api.ip + api, json=data, headers=self.headers,
            verify=False)
        self.log.info(f'response.text:{response.text}')
        self.package_id = response.json()[0]["packageId"]
        self.log.info(f'packageId:{self.package_id}')

        self.log.info('创建clusterTask')
        unused_port = self.common.get_not_used_port(self.pri_node_root)
        api = f'/plugins/base-ops/clusterTask/create'
        data = {"hostId": self.host_id,
                "hostUserId": self.host_user_id,
                "os": self.os_info['os'],
                "cpuArch": self.os_info['cpu_arch'],
                "version": self.pkg_version,
                "versionNum": self.db_version,
                "packageName": f"pkg_{self.user}",
                "packageId": self.package_id,
                "clusterName": f"cluster_{self.user}",
                f"databaseUsername": self.user,
                "databasePassword": macro.COMMON_PASSWD,
                "port": unused_port,
                "installPackagePath": "/opt/dk_batch_install/software/openGauss",
                "installPath": "/opt/dk_batch_install/openGauss/install/app",
                "logPath": "",
                "tmpPath": "",
                "omToolsPath": "",
                "corePath": "",
                "envPath": "",
                "enableCmTool": False,
                "enableGenerateEnvironmentVariableFile": False,
                "xmlConfigPath": "",
                "deployType": "SINGLE_NODE"}
        response = requests.post(
            url=self.base_ops_api.ip + api, json=data, headers=self.headers,
            verify=False)
        self.log.info(f'response.text:{response.text}')
        self.cluster_id = response.json()["msg"]
        self.log.info(f'clusterId:{self.cluster_id}')
        self.assertEqual(response.json()["code"], 200, f'执行成功:{text}')

        self.log.info('创建node')
        api = '/plugins/base-ops/cluster/task/node/create'
        data = {"clusterNodeId": "",
                "clusterId": self.cluster_id,
                "hostId": self.host_id,
                "hostUserId": self.host_user_id,
                "nodeType": "MASTER",
                "dataPath": "/opt/dk_batch_install/openGauss/data/dn",
                "azOwner": "",
                "azPriority": "",
                "isCMMaster": False,
                "cmDataPath": "",
                "cmPort": 1}
        response = requests.post(
            url=self.base_ops_api.ip + api, json=data, headers=self.headers,
            verify=False)
        self.log.info(f'response.text:{response.text}')
        self.assertEqual(response.json()["code"], 200, f'执行成功:{text}')

        text = '----step6:查看草稿箱中并行安装任务列表 expect:可查看到第5步创建的任务----'
        self.log.info(text)
        api = f'/plugins/base-ops/clusterTask/page?' \
              f'name=&openGaussVersion=&pageNum=1&pageSize=10'
        data = {"os": None, "cpuArch": None, "openGaussVersion": None,
                "openGaussVersionNum": None, "status": "DRAFT"}
        response = requests.post(
            url=self.base_ops_api.ip + api, json=data, headers=self.headers,
            verify=False)
        self.log.info(f'response.text:{response.text}')
        self.assertEqual(response.json()["rows"][0]["clusterId"],
                         self.cluster_id, f'执行成功:{text}')

    def tearDown(self):
        text1 = '----step7:删除草稿箱中并行安装任务列表 expect:执行成功----'
        self.log.info(text1)
        api = '/plugins/base-ops/clusterTask/delete'
        data = [self.cluster_id]
        response1 = requests.post(
            url=self.base_ops_api.ip + api, json=data, headers=self.headers,
            verify=False)
        self.log.info(f'response.text:{response1.text}')

        text2 = '----step8:删除安装包 expect:执行成功----'
        self.log.info(text2)
        api = '/plugins/base-ops/installPackageManager/v2/delete/package'
        data = [self.package_id]
        response2 = requests.post(
            url=self.base_ops_api.ip + api, json=data, headers=self.headers,
            verify=False)
        self.log.info(f'response2.text:{response2.text}')

        rm_cmd = f'rm -rf {self.save_pkg_path}'
        self.log.info(rm_cmd)
        rm_res = subprocess.getoutput(rm_cmd)
        self.log.info(rm_res)

        text3 = '----step9:清理环境 expect:成功----'
        self.log.info(text3)
        self.datakit_sh.delete_host()

        self.assertEqual(response1.json()["code"], 200, f'执行成功:{text1}')
        self.assertEqual(response2.json()["code"], 200, f'执行成功:{text2}')
        self.assertNotIn('error', rm_res.lower(), f'执行成功:{text2}')
        self.log.info(f"-----{os.path.basename(__file__)} finsh-----")
